use crate::config::handler_config::Claims;
use crate::entity::sys_user::SysUserBuilder;
use crate::entity::sys_user_role::{SysUserRole, SysUserRoleBuilder};
use crate::entity::Page;
use crate::service::{get_login_org, DATE_FORMAT};
use crate::vo::sys_user_vo::AddUserReqVo;
use crate::{entity::sys_user::SysUser, vo::sys_user_vo::SysUserPageReqVo, SQLX};
use anyhow::anyhow;
use chrono::Local;
use ormlite::model::ModelBuilder;
use ormlite::Model;
use salvo::{Depot, Request};

use super::CLAIMS;

pub struct UserService {}

impl UserService {
    pub async fn page(request: &mut Request, depot: &mut Depot) -> anyhow::Result<Page<SysUser>> {
        let org_id = get_login_org(depot)
            .await?
            .ok_or(anyhow!("org id is null"))?;

        let payload = request.parse_json::<SysUserPageReqVo>().await?;
        let pages = SysUser::query_page(org_id, payload).await?;
        Ok(pages)
    }

    pub async fn add_user(request: &mut Request, depot: &mut Depot) -> anyhow::Result<()> {
        let add_user = request.parse_json::<AddUserReqVo>().await?;
        let current_user = depot.get::<Claims>(CLAIMS).unwrap();
        let sqlx = SQLX.get().ok_or(anyhow!("db error"))?;
        let mut db = sqlx.acquire().await?;
        let sys_user = SysUser {
            user_id: None,
            user_name: add_user.user_name,
            password: add_user.password,
            name: add_user.name,
            phone: add_user.phone,
            admin: add_user.admin,
            remark: add_user.remark,
            state: Some(0),
            create_time: Some(Local::now().format(DATE_FORMAT).to_string()),
            org_id: current_user.org_id,
        }
        .insert(&mut db)
        .await?;

        // add roles ;
        if let Some(roles) = add_user.roles {
            let collect: Vec<SysUserRole> = roles
                .iter()
                .map(|f| SysUserRole {
                    user_role_id: None,
                    user_id: sys_user.user_id,
                    role_id: Some(*f),
                    create_time: Some(Local::now().format(DATE_FORMAT).to_string()),
                })
                .collect();
            for x in collect.into_iter() {
                x.insert(&mut *db).await?;
            }
        }

        Ok(())
    }

    pub async fn del_user(request: &mut Request, depot: &mut Depot) -> anyhow::Result<()> {
        let sqlx = SQLX.get().ok_or(anyhow!("db error"))?;
        let mut db = sqlx.acquire().await?;
        let value = request
            .query::<i64>("user_id")
            .ok_or_else(|| anyhow::anyhow!("user not found"))?;

        SysUserBuilder::default()
            .user_id(Some(value))
            .build()
            .delete(&mut *db)
            .await?;
        SysUserRoleBuilder::default()
            .user_id(Some(value))
            .build()
            .delete(&mut *db)
            .await?;
        Ok(())
    }
}
